﻿
using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Web
{
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Options;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Threading.Tasks;
    using ZXing;
    using ZXing.Common;
    using ZXing.QrCode;
    using ZXing.Rendering;

    public class UtilityController : BaseController
    {
        public UtilityController(IOptions<AppConfig> appconfig, IHttpContextAccessor p_accessor, IWebHostEnvironment p_env, DatabaseService p_databaseService) : base(appconfig, p_accessor, p_env, p_databaseService)
        {
        }

        /// <summary>
        /// 获取服务器时间
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public ApiResult GetServerTime()
        {
            return Success(DateTime.Now);
        }
        /// <summary>
        /// 获取访问者自己的公网ip地址
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public ApiResult GetIp()
        {
            return Success(base.GetClientIp().ToString());
        }

        private static string decodeQrcode(byte[] data)
        {
            var buf = data;
            BarcodeReader reader = new BarcodeReader();
            QRCodeReader qr = new QRCodeReader();

            Bitmap bmp = new Bitmap(new MemoryStream(buf));
            buf = new byte[bmp.Width * bmp.Height * 3];
            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    var c = bmp.GetPixel(x, y);
                    var i = y * bmp.Width * 3 + x * 3;
                    buf[i] = c.R;
                    buf[i + 1] = c.G;
                    buf[i + 2] = c.B;
                }
            }

            var lum = new RGBLuminanceSource(buf, bmp.Width, bmp.Height);

            Result result = qr.decode(new BinaryBitmap(new HybridBinarizer(lum)));

            if (result == null)
            {
                throw new Exception("无法识别,图片中的二维码。");
            }
            else
            {
                return result.Text;
            }

        }

        public static byte[] encodeQrcode(string text, int width = 280)
        {

            var writer = new BarcodeWriter<PixelData>();
            writer.Format = BarcodeFormat.QR_CODE;
            QrCodeEncodingOptions options = new QrCodeEncodingOptions();
            options.DisableECI = true;
            //设置内容编码
            options.CharacterSet = "UTF-8";
            //设置二维码的宽度和高度
            options.Width = width;
            options.Height = width;
            //设置二维码的边距,单位不是固定像素
            options.Margin = 1;
            //容错
            options.ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.Q;
            writer.Options = options;
            writer.Renderer = new PixelDataRenderer();

            var data = writer.Write(text);


            using (var img = new System.Drawing.Bitmap(data.Width, data.Height))
            {
                Graphics graph = Graphics.FromImage(img);
                graph.Clear(Color.White);

                Pen pen = new Pen(Brushes.Black);

                graph.DrawLines(pen, new Point[] { new Point(10, 10), new Point(800, 900) });


                for (int h = 0; h < data.Height; h++)
                {
                    for (int w = 0; w < data.Width; w++)
                    {
                        var i = (h * data.Width + w) * 4;
                        var r = data.Pixels[i + 2];
                        var g = data.Pixels[i + 1];
                        var b = data.Pixels[i];
                        var a = data.Pixels[i + 3];
                        var rect = new RectangleF(w, h, 1, 1);
                        graph.FillRectangle(new SolidBrush(Color.FromArgb(a, r, g, b)), rect);
                    }
                }
                graph.Flush();


                using (var ms = new MemoryStream())
                {
                    img.Save(ms, ImageFormat.Png);
                    var buf = ms.ToArray();
                    return buf;
                }
            }
        }

        /// <summary>
        /// 识别二维码
        /// </summary>
        /// <param name="imgfile"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> DecodeQrcode([FromForm] IFormFile imgfile)
        {
            if (imgfile.Length > 1024 * 1024 * 1024)
            {
                throw new Exception("the file too long.must less than 1M.");
            }
            var buf = new byte[imgfile.Length];
            using (var stream = imgfile.OpenReadStream())
            {
                var length = await stream.ReadAsync(buf, 0, buf.Length);
            }
            var str = decodeQrcode(buf);
            return Success(str);
        }
        /// <summary>
        /// 识别base64图像中的二维码
        /// </summary>
        /// <param name="base64"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult DecodeQrcodeBase64([FromBody] string base64)
        {
            var buf = Convert.FromBase64String(base64);
            var str = decodeQrcode(buf);
            return Success(str);
        }
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        [HttpGet]
        public FileContentResult EncodeQrcode(string text, int width = 280)
        {
            var data = encodeQrcode(text, width);

            using (var ms = new MemoryStream())
            {
                return File(data, "image/png", "code.png");
            }
        }
    }
}
